package com.fanghaoran.service;

import com.fanghaoran.bean.Interaction;
import com.fanghaoran.dao.UserDao;
import com.fanghaoran.entity.Users;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * @Author: win11
 * @Date: 2023/03/22/1:20
 * @Description: 用户相关操作的业务逻辑处理
 */
public class UserService {
    /**
     * 数据库对象 处理数据库相关操作
     */
    private final UserDao userDao = new UserDao();
    // 加密相关参数
    /**
     * 盐的字节数
     */
    private static final int SALT_LENGTH = 16;
    /**
     * 迭代次数
     */
    private static final int ITERATION_COUNT = 1000;

    /**
     * 登录操作
     */
    public Interaction login(String usernameInput, String passwordInput,int isManager) {
        Users user = new Users();

        //判断文本输入框是否为空
        if (usernameInput.length() == 0) {
            return new Interaction("用户名为空", null);
        } else if (passwordInput.length() == 0) {
            return new Interaction("密码为空", null);
        } else {
            //调用数据库操作
            //参数封装成对象传给dao层
            user.setUsername(usernameInput);
            user.setPassword(passwordInput);
            return userDao.login(user,isManager);
        }
    }

    /**
     * 注册操作
     */
    public Interaction register(String usernameInput, String passwordInput, String teleInput, String codeInput, String rCode) throws Exception {
        Users user = new Users();

        //格式校验
        //密码的正则表达式(密码必须至少包含大小写字母+数字 最少六位)
        String pRegex = "\\S*(?=\\S{6,})(?=\\S*\\d)(?=\\S*[A-Z])(?=\\S*[a-z])\\S*$";
        //手机号的正则表达式
        String tRegex = "(?:(?:\\+|00)86)?1\\d{10}$";

        //非数据库操作
        //判断文本输入框是否为空
        if (usernameInput.length() == 0) {
            return new Interaction("用户名为空", null);
        } else if (passwordInput.length() == 0) {
            return new Interaction("密码为空", null);
        } else if (teleInput.length() == 0) {
            return new Interaction("手机号为空", null);
        } else if (codeInput.length() == 0) {
            return new Interaction("验证码为空", null);
        }
        //密码校验
        else if (!passwordInput.matches(pRegex)) {
            return new Interaction("密码不符合规范", null);
        }
        //手机号校验
        else if (!teleInput.matches(tRegex)) {
            return new Interaction("手机号无效", null);
        }
        //验证码校验
        else if (!codeInput.equalsIgnoreCase(rCode)) {
            return new Interaction("验证码错误", null);
        } else {
            //给密码加盐
            //生成盐
            byte[] salt = generateSalt();
            //编码
            String saltBase64 = Base64.getEncoder().encodeToString(salt);
            //加盐加密后的密码
            byte[] hashPassword = hashPassword(passwordInput, salt);
            //编码
            String hashPasswordBase64=Base64.getEncoder().encodeToString(hashPassword);
            //数据库操作
            //输入数据封装成对象
            user.setUsername(usernameInput);
            user.setPassword(hashPasswordBase64);
            user.setSalt(saltBase64);
            user.setTelephone(teleInput);
            return userDao.register(user);

        }
    }

    /**
     * 生成盐的方法
     * */
    public static byte[] generateSalt() {
        //生成高强度随机数
        SecureRandom sr = new SecureRandom();
        //字节数组的长度
        byte[] salt = new byte[SALT_LENGTH];
        //生成随机字节数组
        sr.nextBytes(salt);
        return salt;
    }

    /**
     * 加盐加密的方法
     */
    public static byte[] hashPassword(String password, byte[] salt) {
        try {
            // 拼接密码和盐
            byte[] passwordBytes = password.getBytes();
            byte[] passwordAndSalt = new byte[passwordBytes.length + salt.length];
            System.arraycopy(passwordBytes, 0, passwordAndSalt, 0, passwordBytes.length);
            System.arraycopy(salt, 0, passwordAndSalt, passwordBytes.length, salt.length);

            // 使用 SHA-256算法进行哈希
            MessageDigest md = MessageDigest.getInstance("SHA-256");

            // 执行多次哈希，并返回最终结果
            byte[] hashedBytes = passwordAndSalt;
            for (int i = 0; i < ITERATION_COUNT; i++) {
                //digest计算得出加密后的数据
                hashedBytes = md.digest(hashedBytes);
            }
            return hashedBytes;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            throw new RuntimeException("Hashing the password failed", e);
        }
    }
}
